mod encodes;
mod decodes;

use std::collections::{HashMap, HashSet};
use std::ops::Deref;

use enum_dispatch::enum_dispatch;
#[enum_dispatch]
pub trait RespEncode {
    fn encode(self) -> Vec<u8>;
}


// pub trait RespDecode {
//     fn decode(buf: Self) -> Result<RespFrame,String>;
// }


#[enum_dispatch(RespEncode)]
#[derive(Debug)]
pub  enum RespFrame {
    SimpleString(RespSimpleString),
    Error(RespSimpleError),
    Integer(i64),
    BulkString(BulkString),
    NullBulkString(RespNullBulkString),
    Array(RespArray),
    Null(RespNull),
    NullArray(RespNullArray),
    Boolean(bool),
    Double(f64),
    BigNumber(i64),
    Map(RespMap),
    Set(RespSet),
}
#[derive(Debug)]
pub struct RespSimpleString(String);

impl Deref for RespSimpleString {
    type Target = String;
    fn deref(&self) -> &Self::Target {
       &self.0
    }
}

#[derive(Debug)]
struct RespSimpleError(String);

impl Deref for RespSimpleError {
    type Target = String;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}
#[derive(Debug)]
struct RespNull;

#[derive(Debug)]
struct RespNullArray;

#[derive(Debug)]
struct RespNullBulkString;
#[derive(Debug)]
struct BulkString(Vec<u8>);
#[derive(Debug)]
struct RespArray(Vec<RespFrame>);
#[derive(Debug)]
struct RespMap(HashMap<String,RespFrame>);
#[derive(Debug)]
struct RespSet(HashSet<RespFrame>);
impl Deref for BulkString {
    type Target = Vec<u8>;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}



impl RespSimpleString {
   pub fn new(s:impl Into<String>) -> Self {
       RespSimpleString(s.into())
   }
}



